#pragma once
#include "d3dutil.h"
#include "LevelElement.h"
#include "Vertex.h"
#include <vector>
#include "Light.h"

class NxActor;

class Terrain : public LevelElement
{
public:
	struct InitInfo
	{
		tstring HeightmapFilename;
		tstring LayerMapFilename0;
		tstring LayerMapFilename1;
		tstring LayerMapFilename2;
		tstring LayerMapFilename3;
		tstring LayerMapFilename4;
		tstring BlendMapFilename;
		float HeightScale;
		float HeightOffset;
		UINT NumRows;
		UINT NumCols;
		float CellSpacing;
		bool CastShadows;
	};

	Terrain(Level *pLevel, InitInfo &initinfo);

	virtual ~Terrain(void);

	virtual void Initialize(ContentManager *pContentManager);
	virtual void Tick(const InputState & refInputState){}
	virtual void Draw(const RenderContext* pRenderContext, ID3D10ShaderResourceView* shadowdepthmap = 0);
	virtual void DrawToShadowmap(GraphCamera* pOrtohCam, D3DXMATRIX &mLightVolume
		,ID3D10Effect* BuildShadowMapFX);

	vector<VertexPosNormTex>& GetVextexList() { return m_VecVertices; }

private:
	void CreateEffect(ContentManager *pContentManager);
	void GetEffectVariables(ID3D10Effect* pEffect);
	void BuildVertexBuffer();
	void BuildIndexBuffer();
	void Smooth();
	float Average(UINT i, UINT j);
	bool InBounds(UINT i, UINT j);
	void AddTriangle (unsigned int a, unsigned int b, unsigned c);
	void AddQuad (unsigned int a, unsigned int b, unsigned c, unsigned d);
	void CalcNormal(unsigned int a, unsigned int b, unsigned int c, vector<pair<int, D3DXVECTOR4>> &normallist);
	bool LoadHeightMap();
	void CreateVerticesAndTriangles();
	void DefineInputlayout();
	void CreatePhysicsTerrain();

	vector<pair<int, D3DXVECTOR4>>::iterator FindInFirst(vector<pair<int, D3DXVECTOR4>> &list, int);

	unsigned int GetNumVertices();	
	unsigned int GetNrOfTriangles();
			
	tstring m_FileName;
	tstring m_TextureFileName;
	unsigned int m_NumColumns;
	unsigned int m_NumRows;
	float m_TileSize;
	float m_ScaleHeight;
	float m_Offset;
	
	GraphCamera* m_OrthoCam;

	ID3D10InputLayout*			m_pVertexLayout;
	ID3D10Buffer*				m_pVertexBuffer;
	ID3D10Buffer*				m_pIndexBuffer;
	ID3D10Effect*				m_pDefaultEffect;
	ID3D10EffectTechnique*		m_pDefaultTechnique;
	//ID3D10EffectTechnique*		m_pBuildShadowTechnique;

	ID3D10ShaderResourceView *	m_pTextureRV;
	ID3D10ShaderResourceView* mLayer0;
	ID3D10ShaderResourceView* mLayer1;
	ID3D10ShaderResourceView* mLayer2;
	ID3D10ShaderResourceView* mLayer3;
	ID3D10ShaderResourceView* mLayer4;
	ID3D10ShaderResourceView* mBlendMap;

	ID3D10EffectMatrixVariable* mfxLightWVPVar;
	ID3D10EffectMatrixVariable* m_pWorldViewProjectionVariable;
	ID3D10EffectShaderResourceVariable* mfxLayer0Var;
	ID3D10EffectShaderResourceVariable* mfxLayer1Var;
	ID3D10EffectShaderResourceVariable* mfxLayer2Var;
	ID3D10EffectShaderResourceVariable* mfxLayer3Var;
	ID3D10EffectShaderResourceVariable* mfxLayer4Var;
	ID3D10EffectShaderResourceVariable* mfxBlendMapVar;
	ID3D10EffectShaderResourceVariable* mfxShadowDepthMap;

	ID3D10EffectVectorVariable* m_pEyePosVariable;

	ID3D10EffectVariable* mfxLightVar;

	ID3D10EffectMatrixVariable* m_pWorldVariable;

	vector<unsigned short> m_VecHeightValues;
	vector<VertexPosNormTex> m_VecVertices;
	vector<DWORD> m_VecIndices;

	InitInfo &m_IntInfo;
	// -------------------------
	// Disabling default copy constructor and default assignment operator.
	// If you get a linker error from one of these functions, your class is internally trying to use them. This is
	// an error in your class, these declarations are deliberately made without implementation because they should never be used.
	// -------------------------
	Terrain(const Terrain& t);
	Terrain& operator=(const Terrain& t);
};
